﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CompilerPhase4
{
    public class Token
    {
        #region FIELDS
        string lexeme;                                     //Holds Token Lexeme
        int tokenCode;                                       //Holds Token Code
        string mnemonic;                                 //Holds Token Mnemonic
        MnemonicTable m;                            //Mnemonic table for lookup
        int sTableLoc;         //Location in symbol table (idents and constants)
        #endregion

        /*--------------------------------------------------------------------|
         * Constructor takes in a string to set the lexeme and an int to set  |
         * the token code. Calls the proper method to set the mnemonic.       |
         * ------------------------------------------------------------------*/
        public Token(string lex, int tokCode, MnemonicTable mnem)
        {
            m = mnem;                                 //Create a Mnemonic Table
            lexeme = lex;                                          //Set Lexeme
            tokenCode = tokCode;                               //Set Token Code
            mnemonic = m.GetMnemonic(tokCode);         //Find the mnemonic code
            sTableLoc = -1;                       //Initialize to invalid value
        }
        /*--------------------------------------------------------------------|
         * Getter methods to return the fields. Setter for sTableLoc          |
         * ------------------------------------------------------------------*/
        #region Getter Methods
        public int TokenCode
        {
            get
            {
                return tokenCode;
            }
        }
        public string Lexeme
        {
            get
            {
                return lexeme;
            }
        }
        public string Mnemonic
        {
            get
            {
                return mnemonic;
            }
        }
        public int STableLoc
        {
            get
            {
                return sTableLoc;
            }
            set
            {
                sTableLoc = value;
            }
        }
        #endregion
    }
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    public class TokenTable
    {
        #region FIELDS
        Token[] tokenTable;                          //Array for holding tokens
        int currentIndex;        //Holds the currently open index for insertion
        int max;                                            //Max size of array
        MnemonicTable m;                            //Mnemonic table for lookup
        #endregion

        /*--------------------------------------------------------------------|
         * Constructor: Fills the three given tables  with the requisite vals |
         * ------------------------------------------------------------------*/
        public TokenTable(int size, MnemonicTable mnem)
        {
            m = mnem;
            max = size;
            tokenTable = new Token[size];
            currentIndex = 0;
        }
        /*--------------------------------------------------------------------|
         * Add Token inserts a token to a token table. Takes a string (token) |
         * and an int (token code).                                           |
         * ------------------------------------------------------------------*/
        public void AddToken(string name, int code)
        {
            tokenTable[currentIndex] = new Token(name, code, m);
            currentIndex++;
        }
        /*--------------------------------------------------------------------|
         * CheckExists takes a given lexeme and checks if the lexeme is a     |
         * one-char, two-char or reserve word token.                          |
         * ------------------------------------------------------------------*/
        public int CheckExists(string lexeme)
        {
            int code = 0;                                     //Initialize code
            for(int index = 0; index < max; index++) 
            {
                char ch = lexeme[0];//Grab first char in string
                if (CompareEntry(lexeme, tokenTable[index].Lexeme))
                {                    //If the two-char token is found, set code
                    code = tokenTable[index].TokenCode;
                }
                if (code == 0)                   //If code has not been set
                {
                    code = -1;                          //Set to flag value
                }
            }

            return code;
        }
        /*--------------------------------------------------------------------|
         * CompareEntry takes in a string to compare against a lexeme for     |
         * equality                                                           |
         * ------------------------------------------------------------------*/
        public bool CompareEntry(string temp, string lexeme)
        {
            return string.Equals(temp, lexeme, StringComparison.OrdinalIgnoreCase);
        }
    }
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
}
